package cn.mock.utils;

import org.apache.commons.lang3.math.NumberUtils;

import java.awt.*;

/**
 * @author JiaZH
 * @date 2024-01-12
 */
public class ColorUtils {

    /**
     * rgb转换为hsl
     *
     * @param rgb
     * @return
     */
    public static Integer[] rgb2hsl(Integer[] rgb) {
        int r = rgb[0] / 255,
                g = rgb[1] / 255,
                b = rgb[2] / 255,
                min = NumberUtils.min(r, g, b),
                max = NumberUtils.max(r, g, b),
                delta = max - min,
                h = 0, s, l;
        if (r == max) {
            h = (g - b) / delta;
        } else if (g == max) {
            h = 2 + (b - r) / delta;
        } else if (b == max) {
            h = 4 + (r - g) / delta;
        }

        h = Math.min(h * 60, 360);

        if (h < 0) {
            h += 360;
        }

        l = (min + max) / 2;

        if (max == min) {
            s = 0;
        } else if (l <= 0.5) {
            s = delta / (max + min);
        } else {
            s = delta / (2 - max - min);
        }
        return new Integer[]{h, s * 100, l * 100};
    }

    public static Integer[] rgb2hsv(Integer[] rgb) {
        int r = rgb[0],
                g = rgb[1],
                b = rgb[2],
                min = NumberUtils.min(r, g, b),
                max = NumberUtils.max(r, g, b),
                delta = max - min,
                h = 0, s, v;
        if (max == 0) {
            s = 0;
        } else {
            s = (delta / max * 1000) / 10;
        }

        if (r == max) {
            h = (g - b) / delta;
        } else if (g == max) {
            h = 2 + (b - r) / delta;
        } else if (b == max) {
            h = 4 + (r - g) / delta;
        }

        h = Math.min(h * 60, 360);

        if (h < 0) {
            h += 360;
        }

        v = ((max / 255) * 1000) / 10;

        return new Integer[]{h, s, v};
    }

    public static Integer[] hsl2rgb(Integer[] hsl) {
        int h = hsl[0] / 360,
                s = hsl[1] / 100,
                l = hsl[2] / 100,
                t1, t2, t3, val;
        Integer[] rgb;

        if (s == 0) {
            val = l * 255;
            return new Integer[]{val, val, val};
        }

        if (l < 0.5) {
            t2 = l * (1 + s);
        } else {
            t2 = l + s - l * s;
        }
        t1 = 2 * l - t2;

        rgb = new Integer[]{0, 0, 0};
        for (int i = 0; i < 3; i++) {
            t3 = h + 1 / 3 * -(i - 1);
            if (t3 < 0) {
                t3++;
            }
            if (t3 > 1) {
                t3--;
            }

            if (6 * t3 < 1) {
                val = t1 + (t2 - t1) * 6 * t3;
            } else if (2 * t3 < 1) {
                val = t2;
            } else if (3 * t3 < 2) {
                val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
            } else {
                val = t1;
            }

            rgb[i] = val * 255;
        }

        return rgb;
    }

    public static Integer[] hsl2hsv(Integer[] hsl) {
        int h = hsl[0],
                s = hsl[1] / 100,
                l = hsl[2] / 100,
                sv, v;
        l *= 2;
        s *= (l <= 1) ? l : 2 - l;
        v = (l + s) / 2;
        sv = (2 * s) / (l + s);
        return new Integer[]{h, sv * 100, v * 100};
    }

    public static Integer[] hsv2rgb(Integer[] hsv) {
        double h = (double) hsv[0] / 60;
        double s = (double) hsv[1] / 100;
        double v = (double) hsv[2] / 100;
        double hi = Math.floor(h) % 6;
        double f = h - Math.floor(h);

        int p = (int) (255 * v * (1 - s));
        int q = (int) (255 * v * (1 - (s * f)));
        int t = (int) (255 * v * (1 - (s * (1 - f))));

        int n = (int) (255 * v);

        switch ((int) hi) {
            case 0:
                return new Integer[]{n, t, p};
            case 1:
                return new Integer[]{q, n, p};
            case 2:
                return new Integer[]{p, n, t};
            case 3:
                return new Integer[]{p, q, n};
            case 4:
                return new Integer[]{t, p, n};
            case 5:
                return new Integer[]{n, p, q};
        }
        return new Integer[]{0, 0, 0};
    }

    public static Integer[] hsv2hsl(Integer[] hsv) {
        int h = hsv[0];
        double s = (double) hsv[1] / 100;
        double v = (double) hsv[2] / 100;
        double l, sl;
        l = (2 - s) * v;
        sl = s * v;
        sl /= (l <= 1) ? l : 2 - l;
        l /= 2;
        return new Integer[]{h, (int) (sl * 100), (int) (l * 100)};
    }

    public static String rgb2hex(Integer r, Integer g, Integer b) {
        Color color = new Color(r, g, b);
        return "#" + Integer.toHexString(color.getRGB()).toUpperCase().substring(2);
    }

    public static Integer[] rgb2hex(String color) {
        Color decode = Color.decode(color);
        return new Integer[]{decode.getRed(), decode.getGreen(), decode.getBlue()};
    }

}
